#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
decorator.py - PV装饰器模块

该模块提供了两种PV（过程变量）装饰器：
1. 只读PV装饰器（readOnly）
2. 读写PV装饰器（readWrite）

这些装饰器用于简化PV的访问和控制，提供统一的接口和状态管理。
"""

from epics import PV, caget
import datetime

class readOnly(object):
    """
    只读PV装饰器类
    
    该类用于封装只读PV的访问，提供：
    1. 值读取
    2. 状态监控
    3. 变化回调
    4. 连接状态监控
    """
    
    @property
    def value(self):
        """
        获取PV当前值
        
        返回：
            any: PV的当前值，如果值为空或'[]'则返回None
        """
        if self.pv.value == '' or self.pv.value == '[]':
            return None
        else:
            return self.pv.value

    def onValueChange(self, pvname=None, value=None, conn=None, host=None, timestamp=None, *args, **kwargs):
        """
        PV值变化回调函数
        
        参数：
            pvname (str): PV名称
            value (any): 新的值
            conn (bool): 连接状态
            host (str): 主机名
            timestamp (float): 时间戳
        """
        if self.init_status is True:
            self.timestamp = timestamp
            self.callback_function()
            if (conn is False):
                # 生成PV连接丢失告警
                if self.logging is None:
                    print('ca connection status changed: ', pvname, conn, host)
                else:
                    self.logging.info('ca connection status changed:  %s %s %s', pvname, conn, host)
            else: pass
        else: pass

    @property
    def status(self):
        """
        获取PV状态描述
        
        返回：
            str: PV状态描述字符串
        """
        return self.pvname+' = '+str(self.value)

    def callback_function(self):
        """
        执行回调函数
        """
        if callable(self.callback):
            self.callback(self)
        else: pass

    def __init__(self, name_pv, callback=None, logging=None, *args, **kwargs):
        """
        初始化只读PV装饰器
        
        参数：
            name_pv (tuple): (名称, PV名称)元组
            callback (function, optional): 回调函数
            logging (Logger, optional): 日志记录器
        """
        self.init_status = False
        self.logging = logging
        self.name = name_pv[0]
        self.pvname = name_pv[1]
        caget(self.pvname)
        self.pv = PV(self.pvname, callback=self.onValueChange)
        self.callback = callback
        self.init_status = True

    def __del__(self):
        """
        析构函数，打印删除实例信息
        """
        print('Delete decorator.readonly instance -> '+self.name+' -> '+self.pvname)

class readWrite(object):
    """
    读写PV装饰器类
    
    该类用于封装可读写PV的访问，提供：
    1. 值读写
    2. 状态监控
    3. 变化回调
    4. 连接状态监控
    5. 常用控制命令（开/关、使能/禁用等）
    """
    
    @property
    def value(self):
        """
        获取PV当前值
        
        返回：
            any: PV的当前值，如果值为空或'[]'则返回None
        """
        if self.pv.value == '' or self.pv.value == '[]':
            return None
        else:
            return self.pv.value
            
    @value.setter
    def value(self, _value):
        """
        设置PV值
        
        参数：
            _value (any): 要设置的值
        """
        self.pv.put(_value)

    # 常用控制命令
    @property
    def on(self):
        """设置为开启状态"""
        self.value = 1
    @property
    def off(self):
        """设置为关闭状态"""
        self.value = 0

    @property
    def enabled(self):
        """设置为使能状态"""
        self.value = 1
    @property
    def disabled(self):
        """设置为禁用状态"""
        self.value = 0

    @property
    def prepared(self):
        """设置为已准备状态"""
        self.value = 1
    @property
    def unprepared(self):
        """设置为未准备状态"""
        self.value = 0

    @property
    def busy(self):
        """设置为忙碌状态"""
        self.value = 1
    @property
    def free(self):
        """设置为空闲状态"""
        self.value = 0

    @property
    def triggered(self):
        """设置为已触发状态"""
        self.value = 1
    @property
    def untriggered(self):
        """设置为未触发状态"""
        self.value = 0

    @property
    def status(self):
        """
        获取PV状态描述
        
        返回：
            str: PV状态描述字符串
        """
        return self.pvname+' = '+str(self.value)

    def onValueChange(self, pvname=None, value=None, conn=None, host=None, timestamp=None, *args, **kwargs):
        """
        PV值变化回调函数
        
        参数：
            pvname (str): PV名称
            value (any): 新的值
            conn (bool): 连接状态
            host (str): 主机名
            timestamp (float): 时间戳
        """
        if self.init_status is True:
            self.timestamp = timestamp
            self.callback_function()
            if (conn is False):
                # 生成PV连接丢失告警
                if self.logging is None:
                    print('ca connection status changed: ', pvname, conn, host)
                else:
                    self.logging.info('ca connection status changed:  %s %s %s', pvname, conn, host)
            else: pass
        else: pass

    def callback_function(self):
        """
        执行回调函数
        """
        if callable(self.callback):
            self.callback(self)
        else: pass

    def __init__(self, name_pv, callback=None, logging=None, *args, **kwargs):
        """
        初始化读写PV装饰器
        
        参数：
            name_pv (tuple): (名称, PV名称)元组
            callback (function, optional): 回调函数
            logging (Logger, optional): 日志记录器
        """
        self.init_status = False
        self.logging = logging
        self.name = name_pv[0]
        self.pvname = name_pv[1]
        caget(self.pvname)
        self.pv = PV(self.pvname, callback=self.onValueChange)
        self.timestamp = None
        self.callback = callback
        self.init_status = True

    def __del__(self):
        """
        析构函数，打印删除实例信息
        """
        print('Delete decorator.readwrite instance -> '+self.name+' -> '+self.pvname)

def main():
    """
    主函数（空实现）
    """
    pass

if __name__ == '__main__':
    main()
